package com.fan.shop.views.bean;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.RequestScoped;

import org.apache.log4j.Logger;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.ser.FilterProvider;
import org.codehaus.jackson.map.ser.impl.SimpleBeanPropertyFilter;
import org.codehaus.jackson.map.ser.impl.SimpleFilterProvider;

import com.fan.shop.domain.Item;
import com.fan.shop.domain.PurchaseLine;
import com.fan.shop.domain.PurchaseOrder;
import com.fan.shop.global.JacksonMapper;
import com.fan.shop.model.userclass.PurchaseLineUserClass;
import com.fan.shop.model.userclass.PurchaseOrderUserClass;
import com.fan.shop.services.ItemService;
import com.fan.shop.services.PurchaseLineService;
import com.fan.shop.services.PurchaseOrderService;

@ManagedBean(name = "purchaseOrdersBean")
@RequestScoped
public class PurchaseOrdersBean extends ShopBean {

	private static Logger logger = Logger.getLogger(PurchaseOrdersBean.class);
	@ManagedProperty(value = "#{purchaseOrderService}")
	private PurchaseOrderService purchaseOrderService;

	@ManagedProperty(value = "#{purchaseLineService}")
	private PurchaseLineService purchaseLineService;

	@ManagedProperty(value = "#{itemService}")
	private ItemService itemService;

	private String tableData;
	private int columnsSize;
	private List<String> columnNames;

	private String selectedValue;

	private Map<String, Item> selectedItemsMap;
	private List<PurchaseLineUserClass> selectedPurchaseLines;

	private PurchaseOrder selectedPurchaseOrder;

	public static Logger getLogger() {
		return logger;
	}

	public static void setLogger(Logger logger) {
		PurchaseOrdersBean.logger = logger;
	}

	public PurchaseOrderService getPurchaseOrderService() {
		return purchaseOrderService;
	}

	public void setPurchaseOrderService(
			PurchaseOrderService purchaseOrderService) {
		this.purchaseOrderService = purchaseOrderService;
	}

	public PurchaseLineService getPurchaseLineService() {
		return purchaseLineService;
	}

	public void setPurchaseLineService(PurchaseLineService purchaseLineService) {
		this.purchaseLineService = purchaseLineService;
	}

	public ItemService getItemService() {
		return itemService;
	}

	public void setItemService(ItemService itemService) {
		this.itemService = itemService;
	}

	public PurchaseOrder getSelectedPurchaseOrder() {
		if (selectedValue != null && selectedValue.trim().length() > 0) {
			selectedPurchaseOrder = purchaseOrderService
					.getPurchaseOrder(selectedValue);
		}
		return selectedPurchaseOrder;
	}

	public void setSelectedPurchaseOrder(PurchaseOrder selectedPurchaseOrder) {
		this.selectedPurchaseOrder = selectedPurchaseOrder;
	}

	public String getTableData() {
		ObjectMapper mapper = JacksonMapper.getInstance();

		Set<String> columnNames = new HashSet<String>();
		for (String name : purchaseOrderService.getColumnNames()) {
			columnNames.add(name);

		}
		FilterProvider filters = new SimpleFilterProvider().addFilter(
				"myFilter",
				SimpleBeanPropertyFilter.filterOutAllExcept(columnNames));

		tableData = "\"aaData\": [";
		StringBuffer data = new StringBuffer();

		for (Object obj : purchaseOrderService.getList()) {
			try {
				PurchaseOrderUserClass purchaseLineUserClass = (PurchaseOrderUserClass) obj;
				String line = mapper.writer(filters).writeValueAsString(
						purchaseLineUserClass);
				data = data.append(line);
			} catch (JsonGenerationException e) {
				e.printStackTrace();
			} catch (JsonMappingException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		String tmp = data.toString().replaceAll("\\{[^,:\\{\\}]*:", "[");
		tmp = tmp.replaceAll(",[^,:\\{\\}]*:", ",");

		tableData = tableData + tmp.replace("{", "[").replace("}", "],");
		if (tableData.endsWith(",")) {
			tableData = tableData.substring(0, tableData.length() - 1);
		}

		tableData = tableData + "]";

		return tableData;
	}

	public void setTableData(String tableData) {
		this.tableData = tableData;
	}

	public int getColumnsSize() {
		columnsSize = purchaseOrderService.getColumnsSize();
		return columnsSize;
	}

	public void setColumnsSize(int columnsSize) {
		this.columnsSize = columnsSize;
	}

	public List<String> getColumnNames() {
		columnNames = purchaseOrderService.getColumnNames();
		return columnNames;
	}

	public void setColumnNames(List<String> columnNames) {
		this.columnNames = columnNames;
	}

	public String getSelectedValue() {
		return selectedValue;
	}

	public void setSelectedValue(String selectedValue) {
		this.selectedValue = selectedValue;
	}

	public Map<String, Item> getSelectedItemsMap() {
		return selectedItemsMap;
	}

	public void setSelectedItemsMap(Map<String, Item> selectedItemsMap) {
		this.selectedItemsMap = selectedItemsMap;
	}

	public List<PurchaseLineUserClass> getSelectedPurchaseLines() {

		selectedItemsMap = new HashMap<String, Item>();
		selectedPurchaseLines = new ArrayList<PurchaseLineUserClass>();

		if (selectedValue == null || selectedValue.trim().length() == 0) {
			;
		} else {
			for (PurchaseLine purchaseLine : purchaseOrderService
					.getPurchaseLines(selectedValue)) {
				PurchaseLineUserClass purchaseLineUserClass = (PurchaseLineUserClass) purchaseLineService
						.copy(purchaseLine);
				selectedPurchaseLines.add(purchaseLineUserClass);
				Item item = itemService.getItem(purchaseLine.getId()
						.getItemCode());
				selectedItemsMap.put(item.getItemCode(), item);
			}
		}

		return selectedPurchaseLines;
	}

	public void setSelectedPurchaseLines(
			List<PurchaseLineUserClass> selectedPurchaseLines) {
		this.selectedPurchaseLines = selectedPurchaseLines;
	}

	public String createPurchaseOrderAction() {
		return "purchase_order.faces";
	}

	public String openPurchaseOrderAction() {
		return "purchase_order.faces";
	}

}
